package com.live2d.service;
import com.live2d.entity.mlve.Costume;
import com.live2d.entity.mlve.MlveList;
import java.util.ArrayList;
import com.live2d.entity.json.*;
import com.live2d.entity.mlve.MlveConfig;
import com.zwh.tool.utils.FileUtils;
import com.zwh.tool.utils.JsonUtil;
import com.zwh.tool.utils.Pinyin4jUtils;

import java.util.*;


import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 少女回战live2d
 */
public class ShoujokaisenLive2dService {
    //初始文件路径
    private static String FILE_PATH = "D:\\软件\\逆向\\ces\\xz";
    //移动文件路径Maven projects
    private static String MOVE_FILE_PATH = "D:\\软件\\逆向\\ces\\json\\少回";
    //游戏名称
    private static String GAME_NAME = "少女回战";
    //游戏角色名
    private static String[] HAN_ZI = {"曹操","荀彧","荀攸","贾诩","郭嘉","程昱","戏志才","刘晔","蒋济","陈群","华歆","钟繇","满宠","董昭",
            "王朗","崔琰","毛玠","杜畿","田畴","王修","杨修","辛毗","杨阜","田豫","王粲","蒯越","张继","杜袭","枣祗","任峻","陈矫",
            "郗虑","桓玠","丁仪","丁廙","司马朗","韩暨","韦康","邴原","赵俨","娄圭","贾逵","陈琳","司马懿","张辽","徐晃","夏侯惇",
            "夏侯渊","庞德","张郃","李典","乐进","典韦","曹洪","曹仁","曹彰","曹纯","于禁","许褚","吕虔","李通","文聘","臧霸","郭淮",
            "钟会","邓艾","曹休","张燕","张绣","朱灵","路昭","史涣","韩浩","王凌","孙礼","秦朗","郑文","夏侯尚","毌丘俭","诸葛诞",
            "孙乾","简雍","糜竺","糜芳","庞统","法正","许靖","马良","徐庶","陈震","杨仪","费祎","蒋琬","孟优","黄皓","诸葛亮",
            "关羽","张飞","马超","黄忠","赵云","魏延","关平","周仓","关兴","张苞","陈到","李严","姜维","廖化","马谡","马岱",
            "陈式","雷铜","吴兰","王平","任夔","张翼","马忠","张南","冯习","傅佥","关索","陆逊","张昭","张紘","鲁肃","虞翻","顾雍",
            "诸葛谨","诸葛恪","陆凯","骆统","周鲂","周瑜","吕蒙","甘宁","太史慈","程普","黄盖","韩当","周泰","蒋钦","丁奉","徐盛",
            "陈武","凌操","凌统","潘璋","朱然","孙桓","马忠","孙韶","朱桓","夏恂","周平","全琮","于诠","张角","何进","董卓","袁绍",
            "吕布","袁术","刘表","刘璋","马腾","张鲁","韩遂","公孙瓒","韩馥","刘岱","王匡","张邈","孔伷","陶谦","鲍信","桥瑁","袁遗",
            "孔融","张超","张杨","刘度","赵范","金旋","韩玄","张宝","张梁","程远志","邓茂","马元义","赵弘","韩忠","孙夏","管亥","何仪",
            "刘辟","龚都","裴元绍","高升","张闿","韩暹","李乐","杨奉","董承","王子服","李儒","陈宫","田丰","沮授","审配","许攸","郭图",
            "逢纪","辛评","荀谌","辛毗","陈登","蒯良","王累","韩胤","沮鹄","杨弘","阎象","蒯越","伍孚","李傕","郭汜","颜良","文丑",
            "潘凤","俞涉","武安国","穆顺","华雄","牛辅","张济","樊稠","胡轸","胡车儿","李肃","高顺","张任","高览","曹性","闵纯","纪灵",
            "马休","马铁","高览","袁谭","袁熙","袁尚","高干","麴义","吕翔","吕旷","韩猛","淳于琼","焦触","张南","马延","雷薄","张勋",
            "陈纪","桥蕤","郝萌","侯成","宋宪","魏续","成廉","蔡瑁","张允","黄祖","苏飞","吕公","侯选","程银","李堪","张横","梁兴","董白","小元",
            "成宜","马玩","杨秋","张让","赵忠","封谞","段珪","曹节","侯览","蹇硕","程旷","夏恽","郭胜","吕伯奢","普净","华佗","于吉",
            "左慈","吉平","范增","孙武","韩信","杜甫","李白","白居易","生日","新年","仲夏夜狂想曲","玉藻前","村民","黄月英","文忠","李傕郭汜",
            "王允","祝融","大乔","小乔","张出尘","命运三姐妹","时空之主","哪吒","元稹","张良a","项羽","阿时","焦热","潘凤","双子夏日",
            "龙旋","郝昭","南华老仙","童渊","真田幸村","武田信玄","上杉谦信","织田信长","德川家康","丰臣秀吉","伊达政宗","武圣关羽"};


    public static void main(String[] args) throws Exception {


        File file = new File(FILE_PATH);
        arrangeFile(file);

//        writerFile(file);

        File file1 = new File(MOVE_FILE_PATH);
        batFile(file1);
//        File file1 = new File(FILE_PATH);
//        suffix(file1);
//        File file2 = new File(MOVE_FILE_PATH);
//        mlveFile(file2);

    }

    /**
     * 创建mlve文件
     * @param file
     */
    private static void mlveFile(File file) {
        //获取所有不是目录的文件
        List<File> files = new ArrayList<>();
        FileUtils.list(files,file);
        //筛选.json文件,同时过滤不需要的文件
        List<File> fileList = files.stream().filter(x -> x.getAbsolutePath().endsWith(".json"))
                .filter(x-> !x.getName().contains("Bg_"))
                .filter(x-> !x.getName().contains("ui_"))
                .filter(x-> !x.getName().contains("Ui_"))
                .filter(x-> !x.getName().contains("Sddh"))
                .collect(Collectors.toList());
        //把相同角色的json文件放到一起
        Map<String,List<File>> fileMap = new HashMap<>();
        fileList.forEach(x->{
            String s = x.getName().replace(".json","").replaceAll("[^A-z]", "").toLowerCase();
            List<File> costumeFlie = fileMap.get(s);
            if (costumeFlie == null){
                costumeFlie = new ArrayList<>();
                costumeFlie.add(x);
                fileMap.put(s,costumeFlie);
            }else {
                costumeFlie.add(x);
            }
        });
        //生成mlve配置文件
        MlveConfig mlveConfig = bulidMlve(fileMap);
        FileUtils.saveFile(mlveConfig,MOVE_FILE_PATH+ "\\mlveConfig.mlve");
    }

    /**
     * 生成mlve配置文件
     * @param fileMap
     * @return
     */
    private static MlveConfig bulidMlve(Map<String, List<File>> fileMap) {
        //把角色汉字和拼音对应
        List<String> hanzi = Arrays.asList(HAN_ZI);
        Map<String,String> pingyin_hanzi = new HashMap<>();
        hanzi.forEach(x->pingyin_hanzi.put(Pinyin4jUtils.getFullSpell(x),x));
        //开始创建mlve配置文件
        MlveConfig mlveConfig = new MlveConfig();
        mlveConfig.setName(GAME_NAME);

        List<MlveList> mlveLists = new ArrayList<>();
        fileMap.forEach((x,y)->{
            MlveList mlveList = new MlveList();
            String name = pingyin_hanzi.get(x);
            if (name == null){
                mlveList.setCharacter(x);
            }else {
                mlveList.setCharacter(name);
            }
            List<Costume> costumes = new ArrayList<>();
            y.forEach( z->{
                Costume costume = new Costume();
                costume.setName(z.getName().replace(".json",""));
                costume.setPath(z.getPath());
                costumes.add(costume);
            });
            mlveList.setCostume(costumes);
            mlveLists.add(mlveList);
        });
        mlveConfig.setList(mlveLists);
        return mlveConfig;
    }


    /**
     * 修改文件
     */
    private static void writerFile(File file)  throws Exception{
        if (file.isDirectory()){
            File[] tmps = file.listFiles();
            for (File tmp : tmps) {
                System.out.println(tmp.getName()+":tmps");
                writerFile(tmp);
            }
        }if (!file.getAbsolutePath().endsWith(".json")){
            System.out.println(file.getName()+"：不操作");
            return;
        }
        FileInputStream fileInputStream = null;
        Writer writer = null;
        try{
            String pathName = file.getParentFile().getName();
            fileInputStream = new FileInputStream(file);
            byte[] buf = new byte[1024];
            int len;
            StringBuffer stringBuffer = new StringBuffer();
            while ((len = fileInputStream.read(buf))!= -1){
                stringBuffer.append(new String(buf,0,len));
            }
            ConfigJson configJson = JsonUtil.parse(stringBuffer.toString(), ConfigJson.class);
            configJson.setSkeleton(pathName+ "\\" +configJson.getSkeleton());
            List<Atlases> atlases = configJson.getAtlases();
            for (Atlases atlas : atlases) {
                atlas.setAtlas(pathName+ "\\" +atlas.getAtlas());
                List<String> textures = atlas.getTextures();
                List<String> newTextures = new ArrayList<>();
                textures.forEach(item ->{
                    newTextures.add(pathName+ "\\" +item);
                });
                atlas.setTextures(newTextures);
            }
            System.out.println(configJson);
//            writer = new FileWriter(file);
//            writer.write(JsonUtil.toJson(configJson));
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            fileInputStream.close();
//            writer.close();
        }
    }
    /**
     *整理文件,把相同角色的服装放到一个文件夹里
     */
    private static  void arrangeFile(File file){
        //处理文件后缀
        suffix(file);
        //获取所有不是目录的文件
        List<File> files = new ArrayList<>();
        FileUtils.list(files,file);
        files.forEach(item ->{
            System.out.println(item);
            Pattern compile = Pattern.compile("[A-z]*\\d{2}");
            Matcher m = compile.matcher(item.getName());
            if (m.find()) {
                String group = m.group(0);
                String group1 = null;
                System.out.println(group);
                if (group.contains("Bg_")){
                    group1 = group.substring(3,group.length());
                }else {
                    group1 = group;
                }
                //移动文件
                FileUtils.moveFile(item,MOVE_FILE_PATH + "\\" + group1.substring(0,group1.length()-2) +"\\" + group );
            } else {
                System.out.println("NO MATCH");
            }
        });

    }

    /**
     * 处理文件后缀 asset playable prefab
     * @param file
     */
    private static void suffix(File file) {
        List<File> files = new ArrayList<>();
        FileUtils.list(files,file);
        files.forEach( x->{
            if(x.getAbsolutePath().endsWith(".asset")){
                x.renameTo(new File(x.getParent() +  "\\" + x.getName().substring(0,x.getName().indexOf(".asset"))));
            }
            if(x.getAbsolutePath().endsWith(".playable")){
                x.renameTo(new File(x.getParent() +  "\\" + x.getName().substring(0,x.getName().indexOf(".playable"))));
            }if(x.getAbsolutePath().endsWith(".prefab")){
                x.renameTo(new File(x.getParent() +  "\\" + x.getName().substring(0,x.getName().indexOf(".prefab"))));
            }
        });
    }

    /**
     * 批处理文件,创建配置文件
     * @return
     */
    private static void batFile(File file){
        if (file.isDirectory()) {
            if (judgeFile(file)){
                ConfigJson configJson = bulidConfigJson(file);
                FileUtils.saveFile(configJson,file.getParentFile().getParent()+"\\" +file.getName() +".json");
            }
            File[] tmps = file.listFiles();
            for (File tmp : tmps) {
                System.out.println(tmp.getName() + ":tmps");
                batFile(tmp);
            }
        }
    }

    /**
     * 判断目录下是否有skel、atlas、png文件
     * @param file
     * @return
     */
    private static boolean judgeFile(File file){
        File[] tmps = file.listFiles();
        boolean skel = false;
        boolean atlas = false;
        boolean png = false;
        for (File tmp : tmps) {
            if (tmp.getAbsolutePath().endsWith(".skel")){
                skel = true;
            }
            if (tmp.getAbsolutePath().endsWith(".atlas")){
                atlas = true;
            }
            if (tmp.getAbsolutePath().endsWith(".png")){
                png = true;
            }
        }
        return skel && atlas && png;
    }

    /**
     * 构造配置文件
     * @param file 是个目录，目录下得有skel、atlas、png文件
     * @return
     */
    private static ConfigJson bulidConfigJson(File file){
        String fileName = file.getName();
        String parenName = file.getParentFile().getName();
        ConfigJson configJson = new ConfigJson();
        configJson.setType(9);

        Controllers controllers = new Controllers();
        controllers.setIntimacy_system(new Intimacy_system());
        controllers.setSlot_opacity(new Slot_opacity());
        controllers.setSlot_color(new Slot_color());
        configJson.setControllers(controllers);

        List<Hit_areas> hit_areas = new ArrayList<>();
        Hit_areas hit_areas1 = new Hit_areas();
        hit_areas1.setName("root");
        hit_areas1.setId("root");
        hit_areas1.setWidth(1.5);
        hit_areas1.setHeight(1.5);
        hit_areas.add(hit_areas1);
        configJson.setHit_areas(hit_areas);

        Map<String,List<Idle>> motions = new HashMap<>();
        motions.put("idle",bulidIdles("Stand"));
        motions.put("tap",bulidIdles("Click"));
        motions.put("start",bulidIdles("Open"));
        motions.put("tap_root",bulidIdles("Special01"));
//        motions.put("",bulidIdles("Stand"));
        configJson.setMotions(motions);

        Options options = new Options();
        options.setScale_factor(0.15);
        options.setEdge_padding(false);
        options.setShader("Skeleton-Straight-Alpha");
        configJson.setOptions(options);

        List<Atlases> atlases = new ArrayList<>();
        Atlases atlases1 = new Atlases();
        List<String> texNames = new ArrayList<>();
        List<String> textures = new ArrayList<>();
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.getName().endsWith(".skel")){
                configJson.setSkeleton(parenName + "/" +fileName + "/" +f.getName());
            }
            if (f.getName().endsWith(".atlas")){
                atlases1.setAtlas(parenName + "/" +fileName + "/" + f.getName());
            }
            if (f.getName().endsWith(".png")){
                texNames.add(f.getName().substring(0,f.getName().length()-4));
                textures.add(parenName + "/" +fileName + "/" + f.getName());
            }
        }
        atlases1.setTextures(textures);
        atlases1.setTex_names(texNames);
        atlases.add(atlases1);
        configJson.setAtlases(atlases);
        System.out.println(JsonUtil.toJson(configJson));
        return configJson;
    }
    private static List<Idle> bulidIdles(String stand) {
        List<Idle> idles = new ArrayList<>();
        Idle idle = new Idle();
        idle.setFile(stand);
        idles.add(idle);
        return idles;
    }
}
